<?php
namespace Hphp\Router;
use Hphp\Foundation\Application;
use Hphp\Request\Request;

/**
 * Class Router
 * @package Hphp\Router
 *
 * index.php http://127.0.0.1/public/index.php/h  path_info= /h
 * -> Hphp\Foundation\Http\Kernel->handle()
 *  ->sendRequestThroughRouter()
 *    -> Router->dispatch
 *      1.根据请求查找路由  findRoute
 *          Route::match()
 *          1.1 获取所有路由
 *          1.2 获取到请求的类型[get post...]
 *              1.2.1 根据分类获取到相应的路由、
 *          1.3 获取path_info地址 [index, /index, \index...]
 *              1.3.1 路由的参数处理
 *          1.4 路由的匹配
 *      2. 运行路由----- runRoute() 【闭包,字符串=》控制器 方法】
 *          2.1 判断路由对像的类型
 *              2.1.1 闭包 直接运行  runCallable()
 *              2.1.2 运行控制器  runController()
 *                  2.1.2.1 解析控制器
 *                  2.1.2.2 得到控制器方法
 *              -》 ControllerDispatch::Dispatch()  控制器分发对像
 */
class Router
{
    /**
     * 路由本质实现是会有一个容器在存储解析之后的路由
     */
    protected $routes = [];
    /**
     * @var \Hphp\Foundation\Application
     */
    protected $app;
    /**
     *
     * @var \Hphp\Router\Route
     */
    protected $route;

    protected $namespace;

    /**
     * 定义了访问的类型
     */
    protected $verbs = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];

    public function __construct(Application $app = null)
    {
        $this->app = $app;
        $this->route = new Route($app);
    }

    // ----------------------------------------
    // -------- get/post/any 路由的注册方法 ----
    // ----------------------------------------

    public function get($uri, $action)
    {
        $this->addRoute(['GET'], $uri, $action);
    }

    public function post($uri, $action)
    {
        $this->addRoute(['POST'], $uri, $action);
    }

    public function any($uri, $action)
    {
        $this->addRoute(self::$verbs, $uri, $action);
    }

    public function namespaces($namespace)
    {
//        $this->namespace = $namespace;
//        return $this;

        $this->route->namespaces($namespace);
        return $this;
    }

    public function getRoutes()
    {
        return $this->routes;
    }

    /**
     * 添加路由
     * @param string $methods 请求类型
     * @param string $uri     路由标识
     * @param object $action  控制器方法 | 闭包
     */
    public function addRoute($methods, $uri, $action)
    {
        foreach ($methods as $method ) {
            $this->routes[$method][$uri] = $action;
        }
    }

    /**
     * 注册路由
     */
    public function register($routes)
    {
        require_once $routes;
    }


    // ----------------------------------------
    // -------- 根据request对象处理用户请求 -----
    // ----------------------------------------

    /**
     * 路由分发
     */
    public function dispatch(Request $request)
    {
        // dd($this->routes);
        return $this->runRoute($request, $this->findRoute($request));
    }

    /**
     * 查找路由
     */
    public function findRoute(Request $request)
    {
        $route = $this->route->match($request->getUriPath(), $request->getMethod());

        // 设置共享实例
        $this->app->instance(Route::class, $route);
        return $route;
    }

    /**
     * 运行路由
     */
    public function runRoute(Request $request, Route $route)
    {
        $this->app->make('events')->dispatcher('systemct.log',['运行指定方法']);

        // 事件的处理
        // 中间件
        $route->run($request);
    }
}